﻿using System;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using Microsoft.Practices.ServiceLocation;
using Microsoft.Practices.Unity;
using Sample.Events;
using Sample.Interfaces;
using Sample.Modules.ItemDetail.Views;
using UnityExtensions;

namespace Sample.Modules.ItemDetail
{
    public class Module : IModule
    {
        private readonly IUnityContainer _unityContainer;

        public Module(IUnityContainer unityContainer)
        {
            if (unityContainer == null)
            {
                throw new ArgumentNullException("unityContainer");
            }
            _unityContainer = unityContainer;
        }

        public void Initialize()
        {
            var viewDiscoveryService = _unityContainer.Resolve<IScopedRegionViewRegistry>();
            viewDiscoveryService.RegisterViewWithRegion("ItemHeader", typeof(ItemHeaderView));
            viewDiscoveryService.RegisterViewWithRegion("ItemDetail", typeof(ItemDetailView));
            _unityContainer.Resolve<IEventAggregator>().GetEvent<OpenItemEvent>().Subscribe(OnOpenItemEvent, true);
        }

        private void OnOpenItemEvent(IBook book)
        {
            var region = _unityContainer.Resolve<IRegionManager>().Regions["Items"];
            var view = region.GetView(book.Id.ToString());
            if (view == null)
            {
                view = CreateChildView(book);
                region.Add(view, book.Id.ToString(), true);
            }
            region.Activate(view);
        }

        private object CreateChildView(IBook book)
        {
            var childContainer = _unityContainer.CreateChildContainer();
            // This shouldn't be necessary as long as IServiceLocator is registered with HierarchicalLifetimeManager in the bootstrapper, but still
            // seems to be required for some reason
            childContainer.RegisterInstance(typeof(IServiceLocator), childContainer.Resolve<UnityServiceLocator>());
            childContainer.RegisterInstance(typeof(IBook), book);
            var childView = childContainer.Resolve<ItemView>();
            RegionManager.SetRegionContext(childView, childContainer.Resolve<IServiceLocator>());
            return childView;
        }
    }
}
